#include "smallsatos.h"
#include "int_eeprom.h"
#include "storage.h"

OS_EVENT* eeprom_lock;
OS_EVENT* eeprom_query_mbox;
OS_EVENT* eeprom_response_mbox;

OS_EVENT* get_eeprom_query_mbox(void)
{
	return eeprom_query_mbox;
}

OS_EVENT* get_eeprom_response_mbox(void)
{
	return eeprom_response_mbox;
}

OS_EVENT* get_eeprom_lock(void)
{
	return eeprom_lock;
}

void eeprom_driver(void* pdata)
{
	INT16U i;
	INT16U err;
	eeprom_query* query;
	eeprom_lock = OSSemCreate(1);
	eeprom_query_mbox = OSMboxCreate(NULL);
	eeprom_response_mbox = OSMboxCreate(NULL);

	/* Write fixed values to EEPROM (see protocol...) */
	EEWrite(EE_TYPE_TRAME, 0x0);
	EEWrite(EE_TYPE_TRAME + 256, 0x0F);
	EEWrite(EE_TYPE_TRAME + 512, 0xFF);

	for (;;)
	{
		query = (eeprom_query*)OSMboxPend(eeprom_query_mbox, 0, &err);

		switch (query->type)
		{
			case READ_QUERY:
				for (i=0; i<query->size; i++)
				{
					query->value[i] = EERead(query->address + i);
				}
				OSMboxPost(eeprom_response_mbox, query);
				break;
			case WRITE_QUERY:
				for (i=0; i<query->size; i++)
				{
					EEWrite(query->address + i, query->value[i]);
				}
				break;

			case WIPE_QUERY:
				for (i=0; i<1024; i++)
				{
					EEWrite(i, 0);
				}

				/* Default values */
				EEWrite(0x310, 0xFF);
				EEWrite(0x311, 0xFF);
				EEWrite(0x312, 0xFF);
				EEWrite(0x313, 0xFF);
				EEWrite(0x31A, 0x0F);
				EEWrite(0x31B, 0x0F);
				EEWrite(0x31C, 0x0F);
				EEWrite(0x31D, 0x0F);
				EEWrite(0x31E, 0x0F);
				EEWrite(0x31F, 0xFF);
				EEWrite(0x320, 0xFF);
				EEWrite(0x321, 0xFF);
				EEWrite(0x322, 0xFF);
				EEWrite(0x323, 0xFF);
				EEWrite(0x324, 0xFF);
				EEWrite(0x325, 0xFF);

				EEWrite(EE_TIMER_EMISSION, 5);
				EEWrite(EE_TIMER_TEMPERATURE, 6);
				EEWrite(EE_TIMER_DOSE, 90);
				EEWrite(EE_TIMER_DOSE + 1, 0);
				EEWrite(EE_TIMER_MESURE, 0xD0);
				EEWrite(EE_TIMER_MESURE + 1, 0x2);
				EEWrite(EE_TIMER_PUISSANCE, 90);		
				break;
		}
	}
}

INT8U EERead(INT16U ad) /* Documented in PIC datasheet */
{
	INT8U cpu_sr; /* CPU Status reg. backup (required for the critical mode) */
	INT8U data;
	OS_ENTER_CRITICAL();
	EECON1bits.EEPGD = 0;
	EECON1bits.CFGS = 0;
	EEADRH = (INT8U)((ad >> 8) & 0xFF);
	EEADR = (INT8U)(ad & 0xFF);
	EECON1bits.RD = 1;
	data = EEDATA;
	OS_EXIT_CRITICAL();
	return data;
}

void EEWrite(INT16U ad, INT8U val) /* Documented in PIC datasheet */
{
	INT8U cpu_sr; /* CPU Status reg. backup (required for the critical mode) */
	OS_ENTER_CRITICAL();
	EEADRH = (INT8U)((ad >> 8) & 0xFF);
	EEADR = (INT8U)(ad & 0xFF);
	EEDATA = val;
	EECON1bits.EEPGD = 0;
	EECON1bits.CFGS = 0;
	EECON1bits.WREN = 1;
	INTCONbits.GIE = 0;
	EECON2 = 0x55;
	EECON2 = 0xAA;
	EECON1bits.WR = 1;
	INTCONbits.GIE = 1;
	while (EECON1bits.WR);
	EECON1bits.WREN = 0;
	OS_EXIT_CRITICAL();
}

void shift(eeprom_query* query)
{
	query->address += query->size;
}